<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>OpenLayers 各种类型图层加载示例</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v7.4.0/ol.css">
    <script src="https://cdn.jsdelivr.net/npm/ol@v7.4.0/dist/ol.js"></script>
    <style>
        html, body {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
            overflow: hidden;
        }
        
        .map {
            width: 100%;
            height: 100%;
        }

        .coordinates {
            position: absolute;
            bottom: 10px;
            right: 10px;
            background: rgba(255, 255, 255, 0.8);
            padding: 5px 10px;
            border-radius: 4px;
            font-size: 12px;
            z-index: 1000;
        }

        .layer-switcher {
            position: absolute;
            top: 10px;
            right: 10px;
            background: white;
            padding: 15px;
            border-radius: 4px;
            box-shadow: 0 2px 12px rgba(0,0,0,0.15);
            z-index: 1000;
            max-height: calc(100% - 40px);
            overflow-y: auto;
            min-width: 250px;
        }

        .layer-group {
            margin: 10px 0;
            padding: 12px;
            background: #f5f7fa;
            border-radius: 4px;
        }

        .layer-group h4 {
            margin: 0 0 10px 0;
            font-size: 14px;
            color: #333;
            display: flex;
            align-items: center;
            justify-content: space-between;
        }

        .layer-item {
            margin: 8px 0;
            display: flex;
            align-items: center;
            padding: 5px;
            border-radius: 3px;
            transition: background-color 0.3s;
        }

        .layer-item:hover {
            background: rgba(64, 158, 255, 0.1);
        }

        .layer-item label {
            margin-left: 8px;
            cursor: pointer;
            font-size: 13px;
            flex: 1;
        }

        .opacity-control {
            padding: 8px;
            background: white;
            border-radius: 3px;
            margin-top: 5px;
        }

        .opacity-slider {
            width: 100%;
            margin: 5px 0;
        }

        .opacity-value {
            text-align: right;
            font-size: 12px;
            color: #666;
        }

        /* 添加图层组展开/折叠功能 */
        .group-header {
            cursor: pointer;
            user-select: none;
        }

        .group-header:hover {
            color: #409EFF;
        }

        .group-content {
            overflow: hidden;
            transition: max-height 0.3s ease-out;
        }

        .collapse-icon {
            font-size: 12px;
            transition: transform 0.3s;
        }

        .collapsed .collapse-icon {
            transform: rotate(-90deg);
        }

        .collapsed .group-content {
            max-height: 0;
        }
    </style>
</head>
<body>
    <div id="map" class="map"></div>
    <div id="coordinates" class="coordinates"></div>
    
    <!-- 图层控制面板 -->
    <div class="layer-switcher">
        <!-- 底图组 -->
        <div class="layer-group">
            <h4 class="group-header">
                <span>底图</span>
                <span class="collapse-icon">▼</span>
            </h4>
            <div class="group-content">
                <div class="layer-item">
                    <input type="radio" name="baseLayer" id="gaode" checked>
                    <label for="gaode">高德底图</label>
                </div>
                <div class="layer-item">
                    <input type="radio" name="baseLayer" id="satellite">
                    <label for="satellite">卫星影像</label>
                </div>
            </div>
        </div>

        <!-- REST图层组 -->
        <div class="layer-group">
            <h4 class="group-header">
                <span>REST图层</span>
                <span class="collapse-icon">▼</span>
            </h4>
            <div class="group-content">
                <div class="layer-item">
                    <input type="checkbox" id="restLayer">
                    <label for="restLayer">ArcGIS REST服务</label>
                </div>
                <div class="opacity-control">
                    <div class="opacity-value">透明度: <span id="restOpacityValue">100%</span></div>
                    <input type="range" 
                           id="restOpacity" 
                           class="opacity-slider" 
                           min="0" 
                           max="1" 
                           step="0.1" 
                           value="1">
                </div>
            </div>
        </div>

        <!-- WMTS图层组 -->
        <div class="layer-group">
            <h4 class="group-header">
                <span>WMTS图层</span>
                <span class="collapse-icon">▼</span>
            </h4>
            <div class="group-content">
                <div class="layer-item">
                    <input type="checkbox" id="wmtsLayer">
                    <label for="wmtsLayer">天地图矢量注记</label>
                </div>
                <div class="opacity-control">
                    <div class="opacity-value">透明度: <span id="wmtsOpacityValue">100%</span></div>
                    <input type="range" 
                           id="wmtsOpacity" 
                           class="opacity-slider" 
                           min="0" 
                           max="1" 
                           step="0.1" 
                           value="1">
                </div>
            </div>
        </div>

        <!-- SuperMap图层组 -->
        <div class="layer-group">
            <h4 class="group-header">
                <span>SuperMap图层</span>
                <span class="collapse-icon">▼</span>
            </h4>
            <div class="group-content">
                <div class="layer-item">
                    <input type="checkbox" id="supermapLayer">
                    <label for="supermapLayer">SuperMap iServer</label>
                </div>
                <div class="opacity-control">
                    <div class="opacity-value">透明度: <span id="supermapOpacityValue">100%</span></div>
                    <input type="range" 
                           id="supermapOpacity" 
                           class="opacity-slider" 
                           min="0" 
                           max="1" 
                           step="0.1" 
                           value="1">
                </div>
            </div>
        </div>

        <!-- EPSG:4326图层组 -->
        <div class="layer-group">
            <h4 class="group-header">
                <span>4326坐标系图层</span>
                <span class="collapse-icon">▼</span>
            </h4>
            <div class="group-content">
                <div class="layer-item">
                    <input type="checkbox" id="layer4326">
                    <label for="layer4326">天地图 EPSG:4326</label>
                </div>
                <div class="opacity-control">
                    <div class="opacity-value">透明度: <span id="layer4326OpacityValue">100%</span></div>
                    <input type="range" 
                           id="layer4326Opacity" 
                           class="opacity-slider" 
                           min="0" 
                           max="1" 
                           step="0.1" 
                           value="1">
                </div>
            </div>
        </div>
    </div>

    <script>
        // 初始化地图
        function initMap() {
            // 创建图层
            const layers = {
                base: {
                    gaode: new ol.layer.Tile({
                        source: new ol.source.XYZ({
                            url: 'https://webst0{1-4}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
                            crossOrigin: 'anonymous'
                        }),
                        // visible: false
                    }),
    
                    satellite: new ol.layer.Tile({
                        source: new ol.source.XYZ({
                            url: 'https://webst0{1-4}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}&layer=satellite',
                            crossOrigin: 'anonymous'
                        }),
                        visible: false
                    })
                },
                
                // 业务图层
                business: {
                    rest: new ol.layer.Tile({
                        source: new ol.source.TileArcGISRest({
                            url: 'https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer',
                            crossOrigin: 'anonymous'
                        }),
                        visible: false
                    }),
                    wmts: new ol.layer.Tile({
                        source: new ol.source.WMTS({
                            url: 'https://t{0-7}.tianditu.gov.cn/cva_w/wmts?tk=8c88eba266a165eac9c085724708f2f9',
                            layer: 'cva',
                            format: 'tiles',
                            matrixSet: 'w',
                            style: 'default',
                            projection: 'EPSG:3857',
                            tileGrid: new ol.tilegrid.WMTS({
                                extent: ol.proj.get('EPSG:3857').getExtent(),
                                origin: ol.extent.getTopLeft(ol.proj.get('EPSG:3857').getExtent()),
                                resolutions: (() => {
                                    const size = ol.extent.getWidth(ol.proj.get('EPSG:3857').getExtent()) / 256;
                                    const resolutions = new Array(18);
                                    for (let z = 0; z < 18; z++) {
                                        resolutions[z] = size / Math.pow(2, z);
                                    }
                                    return resolutions;
                                })(),
                                matrixIds: Array(18).fill(0).map((_, i) => i),
                                tileSize: [256, 256]
                            }),
                            wrapX: true
                        }),
                        visible: false
                    }),
                    supermap: new ol.layer.Tile({
                        source: new ol.source.TileWMS({
                            url: 'http://support.supermap.com.cn:8090/iserver/services/map-china400/wms111/China',
                            params: {
                                'LAYERS': 'China',
                                'FORMAT': 'image/png',
                                'VERSION': '1.1.1',
                                'TILED': true
                            },
                            crossOrigin: 'anonymous',
                            projection: 'EPSG:3857',
                            tileGrid: new ol.tilegrid.TileGrid({
                                origin: [-20037508.34, -20037508.34],
                                resolutions: (() => {
                                    const maxResolution = ol.extent.getWidth(ol.proj.get('EPSG:3857').getExtent()) / 256;
                                    const resolutions = new Array(22);
                                    for (let i = 0; i < 22; i++) {
                                        resolutions[i] = maxResolution / Math.pow(2, i);
                                    }
                                    return resolutions;
                                })()
                            })
                        }),
                        visible: false
                    }),
                    layer4326: new ol.layer.Tile({
                        source: new ol.source.WMTS({
                            url: 'https://t{0-7}.tianditu.gov.cn/vec_c/wmts?tk=8c88eba266a165eac9c085724708f2f9',
                            layer: 'vec',
                            format: 'tiles',
                            matrixSet: 'c',
                            style: 'default',
                            projection: 'EPSG:4326',
                            tileGrid: new ol.tilegrid.WMTS({
                                origin: [-180, 90],
                                resolutions: (() => {
                                    const res = [];
                                    const maxZoom = 18;
                                    const initialResolution = 1.40625;
                                    for (let i = 1; i <= maxZoom; i++) {
                                        res.push(initialResolution / Math.pow(2, i));
                                    }
                                    return res;
                                })(),
                                matrixIds: Array(18).fill(0).map((_, i) => (i + 1).toString()),
                                tileSize: [256, 256]
                            }),
                            wrapX: true
                        }),
                        visible: false
                    })
                }
            };

            // 创建地图
            const map = new ol.Map({
                target: 'map',
                layers: [
                    ...Object.values(layers.base),
                    ...Object.values(layers.business)
                ],
                view: new ol.View({
                    center: ol.proj.fromLonLat([116.391389, 39.907143]),  // 天安门坐标
                    zoom: 12,  // 调整缩放级别以更好地显示天安门区域
                    // projection: 'EPSG:3857'  // 明确指定投影
                })
            });

            // 底图切换事件
            function switchBaseLayer(id) {
                Object.keys(layers.base).forEach(key => {
                    layers.base[key].setVisible(key === id);
                });
            }

            document.getElementById('gaode').onchange = () => switchBaseLayer('gaode');
            document.getElementById('satellite').onchange = () => switchBaseLayer('satellite');

            // 业务图层控制
            function setupLayerControl(layerId, layer) {
                const checkbox = document.getElementById(layerId);
                if (!checkbox) return;

                checkbox.onchange = (e) => layer.setVisible(e.target.checked);
                
                // 透明度控制
                const opacitySlider = document.getElementById(`${layerId}Opacity`);
                const opacityValue = document.getElementById(`${layerId}OpacityValue`);
                if (opacitySlider && opacityValue) {
                    opacitySlider.oninput = (e) => {
                        const value = parseFloat(e.target.value);
                        layer.setOpacity(value);
                        opacityValue.textContent = Math.round(value * 100) + '%';
                    };
                }
            }

            // 确保 DOM 加载完成后再设置控制器
            const layerControls = {
                'restLayer': layers.business.rest,
                'wmtsLayer': layers.business.wmts,
                'supermapLayer': layers.business.supermap,
                'layer4326': layers.business.layer4326
            };
            
            // 等待所有DOM元素加载完成
            window.addEventListener('DOMContentLoaded', () => {
                Object.entries(layerControls).forEach(([id, layer]) => {
                    setupLayerControl(id, layer);
                });
            });

            // 图层组展开/折叠功能
            window.addEventListener('DOMContentLoaded', () => {
                document.querySelectorAll('.group-header').forEach(header => {
                    header.onclick = function() {
                        const group = this.closest('.layer-group');
                        group.classList.toggle('collapsed');
                    };
                });
            });

            // 显示坐标
            map.on('pointermove', function(evt) {
                const coords = ol.proj.transform(evt.coordinate, 'EPSG:3857', 'EPSG:4326');
                document.getElementById('coordinates').innerHTML = 
                    `经度: ${coords[0].toFixed(6)}, 纬度: ${coords[1].toFixed(6)}`;
            });

            // 添加比例尺控件
            map.addControl(new ol.control.ScaleLine({
                units: 'metric'
            }));
        }

        // 等待 OpenLayers 加载完成
        if (window.ol) {
            initMap();
        } else {
            document.querySelector('script[src*="ol.js"]').onload = initMap;
        }
    </script>
</body>
</html> 